package com.loklok.confuse.ui;

import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.uiDesigner.core.GridConstraints;
import com.intellij.uiDesigner.core.GridLayoutManager;
import com.intellij.uiDesigner.core.Spacer;
import com.loklok.confuse.extend.VmFileType;
import com.loklok.confuse.extension.PathConfigSettingCache;
import com.loklok.confuse.model.CodePathConfig;
import com.loklok.confuse.util.*;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class GenerateVmCodeDialog extends JDialog {
    private JPanel contentPane;
    private JButton buttonOK;
    private JTextField filePrefix;
    private JRadioButton voRadioButton;
    private JRadioButton controllerRadioButton;
    private JRadioButton dtoRadioButton;
    private JButton buttonCancel;

    public GenerateVmCodeDialog(AnActionEvent anActionEvent) {
        setContentPane(contentPane);
        setTitle("codeConfuse");
        setSize(800, 300);
        setLocation(600, 200);
        setModal(true);
        setResizable(true);
        getRootPane().setDefaultButton(buttonOK);

        PathConfigSettingCache state = PathConfigSettingCache.getInstance(anActionEvent.getProject());
        Project project = anActionEvent.getProject();
        if (state == null || state.getConfig() == null || state.getConfig().requiredFieldsEmpty()) {
            CommonUtil.configureMessageReminders(project);
            return;
        }

        CodePathConfig config = state.getConfig();

        buttonOK.addActionListener(e -> {

            if(StringUtils.isEmpty(filePrefix.getText()) ||
                    !(voRadioButton.isSelected() || dtoRadioButton.isSelected() || controllerRadioButton.isSelected())){
                Messages.showInfoMessage("类前缀和选择类型都是必填!", "Error");
                return;
            }

            // 获取鼠标点击的文件
            VirtualFile file = anActionEvent.getData(CommonDataKeys.VIRTUAL_FILE);
            if (file == null) {
                Messages.showInfoMessage("No file is selected.", "Info");
                return;
            }

            String path = file.getPath();
            String parentDirectoryName = CommonUtil.getParentDirectoryName(path);


            // 获取文件内容
            Document document = FileDocumentManager.getInstance().getDocument(file);
            if (document == null) {
                Messages.showInfoMessage("Unable to get document for the file.", "Error");
                return;
            }

            ProgressManager.getInstance().run(new Task.Backgroundable(project, "Generating Files", false) {
                @Override
                public void run(@NotNull ProgressIndicator indicator) {

                    indicator.setText("ConfuseCode plugin Generating files...");
                    indicator.setFraction(0.0); // 初始化进度

                    doGenVmCode(document, config, parentDirectoryName, file, anActionEvent, project);

                    indicator.setFraction(1.0); // 完成进度
                    indicator.setText("ConfuseCode plugin File generation complete!");
                }
            });
            onOK();
        });

        // call onCancel() when cross is clicked
        setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
        addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                onCancel();
            }
        });

        // call onCancel() on ESCAPE
        contentPane.registerKeyboardAction(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                onCancel();
            }
        }, KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
    }

    private void doGenVmCode(Document document, CodePathConfig config, String parentDirectoryName, VirtualFile file, AnActionEvent anActionEvent, Project project) {
        String content = document.getText();

        String voDtoPath = getVoDtoPath(config);

        content = content.replace(CommonUtil.pathToDeclarePackage( voDtoPath+ "/" + parentDirectoryName), "$!{vo.pck}");

        String promptTemplate = getPromptTemplate(content, config);
        String vmBody = OpenAIUtil.getVmBody(config.getDeepSeekApiKey(), promptTemplate);
        if(StringUtils.isEmpty(vmBody)){
            ApplicationManager.getApplication().invokeLater(() -> Messages.showMessageDialog("大模型生成模板为空", "error massage:", Messages.getErrorIcon()));
            throw new RuntimeException();
        }
        String fileName = file.getName().replace(".java", ".java.vm");
        fileName = fileName.replace(filePrefix.getText(), "");
        String fullPck = CommonUtil.pathToPackage(CommonUtil.pathJoint(voDtoPath, parentDirectoryName));
        LocalFileUtils.writeFile(anActionEvent, project, fullPck, fileName, vmBody, VmFileType.INSTANCE);
        LocalFileUtils.resetApplyToAll(project);
    }

    @Nullable
    private String getVoDtoPath(CodePathConfig config) {
        String voDtoPath = null;
        if(voRadioButton.isSelected()){
            voDtoPath = config.getVoPath();
        } else if(dtoRadioButton.isSelected()){
            voDtoPath = config.getRequestPath();
        } else if(controllerRadioButton.isSelected()){
            voDtoPath = config.getControllerPath();
        }
        return voDtoPath;
    }

    private String getPromptTemplate(String content, CodePathConfig config) {
        if(voRadioButton.isSelected()){

            return PromptTemplate.getVoPromptTemplate(filePrefix.getText(), content);
        } else if(dtoRadioButton.isSelected()){
            return PromptTemplate.getDtoPromptTemplate(filePrefix.getText(), content);
        } else if(controllerRadioButton.isSelected()){
            return PromptTemplate.getControllerPromptTemplate(filePrefix.getText(), content);
        }
        return null;
    }

    private void onOK() {
        // add your code here
        dispose();
    }

    private void onCancel() {
        // add your code here if necessary
        dispose();
    }

    {
// GUI initializer generated by IntelliJ IDEA GUI Designer
// >>> IMPORTANT!! <<<
// DO NOT EDIT OR ADD ANY CODE HERE!
        $$$setupUI$$$();
    }

    /**
     * Method generated by IntelliJ IDEA GUI Designer
     * >>> IMPORTANT!! <<<
     * DO NOT edit this method OR call it in your code!
     *
     * @noinspection ALL
     */
    private void $$$setupUI$$$() {
        contentPane = new JPanel();
        contentPane.setLayout(new GridLayoutManager(2, 1, new Insets(10, 10, 10, 10), -1, -1));
        final JPanel panel1 = new JPanel();
        panel1.setLayout(new GridLayoutManager(1, 2, new Insets(0, 0, 0, 0), -1, -1));
        contentPane.add(panel1, new GridConstraints(1, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, 1, null, null, null, 0, false));
        final Spacer spacer1 = new Spacer();
        panel1.add(spacer1, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_WANT_GROW, 1, null, null, null, 0, false));
        final JPanel panel2 = new JPanel();
        panel2.setLayout(new GridLayoutManager(1, 2, new Insets(0, 0, 0, 0), -1, -1, true, false));
        panel1.add(panel2, new GridConstraints(0, 1, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false));
        buttonOK = new JButton();
        buttonOK.setText("OK");
        panel2.add(buttonOK, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
        buttonCancel = new JButton();
        buttonCancel.setText("Cancel");
        panel2.add(buttonCancel, new GridConstraints(0, 1, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
        final JPanel panel3 = new JPanel();
        panel3.setLayout(new GridLayoutManager(1, 1, new Insets(0, 0, 0, 0), -1, -1));
        contentPane.add(panel3, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false));
    }

    /**
     * @noinspection ALL
     */
    public JComponent $$$getRootComponent$$$() {
        return contentPane;
    }
}
